package com.foreveross.proxyip.core.pools.thread;

import java.util.List;
import java.util.concurrent.Callable;

import org.apache.log4j.Logger;

import com.foreveross.proxyip.core.pools.AvailablePool;
import com.foreveross.proxyip.core.pools.ChannelPool;
import com.foreveross.proxyip.core.pools.DbPool;
import com.foreveross.proxyip.core.pools.PoolsManager;
import com.foreveross.proxyip.core.redis.RedisExecutor;
import com.foreveross.proxyip.entity.ProxyIpBean;
import com.foreveross.proxyip.exception.ProxyIpServiceException;
import com.foreveross.proxyip.infra.base.ddd.repository.IBaseRepository;
import com.foreveross.proxyip.util.SerializeUtil;

/**
 * 池的检入线程类
 * 
 * @author lyq
 * 
 */
@SuppressWarnings("rawtypes")
public class CheckInValidateThread implements Callable {
	protected static final Logger log = Logger.getLogger(PoolsManager.class);
	private List tempIpList = null;
	IBaseRepository repository = null;// 提供jpa数据库操作的支持
	AvailablePool pool = null;

	// Integer proxyMax = Integer.parseInt( PropertyUtils.getProperty(Config.POOL_PROXY_MAX, ProxyIpPropertiesLoader.CONFIG_FILE));
	public void setTempIpList(List tempIpList) {
		this.tempIpList = tempIpList;
	}

	public CheckInValidateThread(List tempIpList, AvailablePool pool,
			IBaseRepository repository) {
		this.tempIpList = tempIpList;
		this.repository = repository;
		this.pool = pool;
	}

	public Object call() {

		try {
			long size = pool.size();
			
			if (size >= pool.getProxyMax()) {
				return null;
			}
			
			for (int i = 0; i < tempIpList.size(); i++) {
				ProxyIpBean bean = null;
				boolean addSuss = false, containBean = true;
				
				try {
					final String ip = (String) tempIpList.get(i);
					
					if (ip == null) {
						continue;
					}
					
					bean = (ProxyIpBean) this.pool.ipStoreMap.get(ip);
					
					if (bean == null) {
						this.pool.poolIpMap.remove(ip);
						pool.removeMarkIpAlreadyUsed(ip);
						continue;
					}

					// 这个ip正在被其它线程验证，可是己在池中则不检查
					if (this.pool.contains(ip) || this.pool.isIpLock(ip)) {
						continue;
					}
					
					Integer bool = 1;
					
					// 只有当开启了渠道池校验或是除渠道池之外的池ip数大于4000时就校验
					if (pool instanceof ChannelPool) {
						if (pool.isOpenChannelPoolCheckInVerify) {
							bool = pool.getValidate().validate(bean, 1);
						}
					} else {
						if (size > 4000) {
							bool = pool.getValidate().validate(bean, 1);
						}
					}

					if (bool != 0) {
						addSuss = true;
						if (pool.size() < pool.getProxyMax()) {
							//	addSuss = true;
							if ((!pool.contains(bean.getCompletionIP())) && !DbPool.POOL_CODE.equals(pool.poolSign)) {// 已经存在了
								bean.getUsingKeys().add(this.pool.poolSign);
							}
						}
					}

					int update = -1;
					
					if (!pool.ipStoreMap.containsKey(bean.getCompletionIP())) {// 新增ip，
						containBean = false;
					} else {// 包括
						update = pool.beforeUpdate(bean);
					}
					
					// Jedis jedis = null;

					// try{
					final int _update = update;
					final boolean _addSuss = addSuss, _containBean = containBean;
					final ProxyIpBean _bean = bean;

					new RedisExecutor<Long>() {
						@Override
						public Long run() throws Exception {

							int update = _update;
							tran = jedis.multi();
							
							if (_addSuss) {
								pool.addIp2ChannelTime(_bean);
								if (!_containBean) {
									// bean.getUsingKeys().add(this.pool.poolSign);
									pool.ipStoreMap.set(tran, _bean.getCompletionIP(),_bean);
									update = -1;// 刚刚新增进去不需要验证
									if (pool instanceof ChannelPool) {
										pool.redisManager.setnx(pool.getIpLastCheckinTimeKey(_bean),"Checkin",pool.checkInSepTime / 1000);
									}
								}
								
								pool.set(tran,_bean.getChannelUseCount().get(pool.poolSign), _bean);
							}
							
							if (update == 1 || (DbPool.POOL_CODE.equals(pool.poolSign) && _addSuss)) {
								_bean.setCheckTime(System.currentTimeMillis());
								tran.set(_bean.getCompletionIP().getBytes(), SerializeUtil.serialize(_bean));// 覆盖，不用成为僵尸了。
								tran.expire(_bean.getCompletionIP().getBytes(), 360000);
							} else if (update == 0) {
								tran.del(_bean.getCompletionIP().getBytes());
							}
							// 验证结果要保存到redis
							tran.exec();
							return null;
						}
					}.exec();
					
					// 如果要删除的则同时也把标记删除
					if (_update == 0 || bool == 0) {
						pool.removeMarkIpAlreadyUsed(bean.getCompletionIP());
					}
				} catch (Exception e) {
					log.error(ProxyIpServiceException.getStackTrace(e));
				} finally {
					if (bean != null) {
						this.pool.unIpLock(bean.getCompletionIP());
						// lock.unlock();
					}
				}
			}
		} catch (Exception e) {
			log.error(ProxyIpServiceException.getStackTrace(e));
		} finally {
			tempIpList.clear();
			// valids.clear();
		}
		// log.debug(pool.poolSign + " checkIn finish..");
		return null;
	}

}
